package com.dianban.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {

	public static final char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

	public final static String hash(String input) {
		return hash(input.getBytes());
	}

	public final static String hash(byte[] input) {
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			// 使用指定的字节更新摘要
			md5.update(input);
			// 获得密文
			byte[] digest = md5.digest();
			// 把密文转换成十六进制的字符串形式
			int j = digest.length;
			char result[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = digest[i];
				result[k++] = hexDigits[byte0 >>> 4 & 0xf];
				result[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(result);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * MD5 加密
	 */
	public static String getMD5Str(String str) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");

			messageDigest.reset();

			messageDigest.update(str.getBytes("UTF-8"));
		} catch (NoSuchAlgorithmException e) {
			//System.out.println("NoSuchAlgorithmException caught!");
			e.printStackTrace();
			System.exit(-1);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}

		return md5StrBuff.toString();
	}

	/**
	 * MD5 加密
	 */
	public static String getGBKMD5Str(String str) {
		MessageDigest messageDigest = null;

		try {
			messageDigest = MessageDigest.getInstance("MD5");

			messageDigest.reset();
			messageDigest.update(str.getBytes("GBK"));
		} catch (NoSuchAlgorithmException e) {
			//System.out.println("NoSuchAlgorithmException caught!");
			e.printStackTrace();
			System.exit(-1);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		byte[] byteArray = messageDigest.digest();

		StringBuffer md5StrBuff = new StringBuffer();

		for (int i = 0; i < byteArray.length; i++) {
			if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
				md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
			else
				md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
		}
		return md5StrBuff.toString();
	}

    /** 
     * 根据文件对象计算文件的MD5 
     * @param file 
     * @return 
     * @throws IOException 
     */ 
	public static String getFileMD5String(File file) throws IOException, NoSuchAlgorithmException { 
    	MessageDigest messageDigest = null;
    	FileInputStream in = null;
    	FileChannel ch = null;
    	MappedByteBuffer byteBuffer = null;
    	try {
    		messageDigest = MessageDigest.getInstance("MD5");
    		in = new FileInputStream(file);
			ch = in.getChannel(); 
    		byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, 0, file.length()); 
    		messageDigest.update(byteBuffer); 
    		return bufferToHex(messageDigest.digest()); 
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			if(in!=null) in.close(); 
			if(ch!=null) ch.close();
			if(byteBuffer!=null) byteBuffer.clear();
			if(messageDigest!=null) {messageDigest.reset();messageDigest=null;}
			if(file!=null) file.delete();
		}
    } 
    
//    public static String getFileMD5String(MultipartFile mFile) throws IOException { 
//    	MessageDigest messageDigest = null;
//    	BufferedInputStream is = null;
//		ByteArrayInputStream bis = null;
//		File file = null;
//		FileChannel ch = null;
//		MappedByteBuffer byteBuffer = null;
//		ByteArrayOutputStream out = null;
//    	try {
//    		messageDigest = MessageDigest.getInstance("MD5");
//  		  	bis = new ByteArrayInputStream(mFile.getBytes());
//  		  	is = new BufferedInputStream(bis);
//  		  	out = new ByteArrayOutputStream(is.available());
//  		  	byte[] cache = new byte[8192]; 
//  		  	for(int i = is.read(cache);i != -1;i = is.read(cache)){  
//  		  		out.write(cache, 0, i); 
//  		  	}
//	        messageDigest.update(out.toByteArray()); 
//	        return bufferToHex(messageDigest.digest()); 
//		} catch (Exception e) {
//			e.printStackTrace();
//			return null;
//		}finally{
////			if(bis!=null) bis.close();
////			if(ch!=null) ch.close();
////			if(byteBuffer!=null) byteBuffer.clear();
//			if(messageDigest!=null) {messageDigest.reset();messageDigest=null;}
////			if(file!=null) file.delete();
//		}
//    } 
    
    private static String bufferToHex(byte bytes[]) { 
        return bufferToHex(bytes, 0, bytes.length); 
    } 

    private static String bufferToHex(byte bytes[], int m, int n) { 
        StringBuffer stringbuffer = new StringBuffer(2 * n); 
        int k = m + n; 
        for (int l = m; l < k; l++) { 
            appendHexPair(bytes[l], stringbuffer); 
        } 
        return stringbuffer.toString(); 
    } 

    private static void appendHexPair(byte bt, StringBuffer stringbuffer) { 
        char c0 = hexDigits[(bt & 0xf0) >> 4]; 
        char c1 = hexDigits[bt & 0xf]; 
        stringbuffer.append(c0); 
        stringbuffer.append(c1); 
    } 
    
}